/*************************************************************
Date: 2010-12
Description: api接口定义
***********************************************************/
#ifndef __TRMEM_CACHE_LIB_H__
#define __TRMEM_CACHE_LIB_H__

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <string>
#include <vector>
#include <map>
using namespace std;
#include "common_define.h"
#include "coder_define.h"
#include "buffer.h"
#define MAJOR "3"
#define MIDDLE "0"
#define MINOR "14"

#define API_VERSION "Project Ver: Opencloud_V1.3.0\n"\
	"Ver " MAJOR "." MIDDLE "." MINOR "\n"\
	"*2013-07-17 v3.0.14 add incr_value return incr result; add api incr_create\n"\
	"*2013-04-07 v3.0.13 change connect time limit to >= 50ms, read/write limit to > 1ms\n"\
	"*2013-03-12 v3.0.12 support client passwd and client api flag\n"\
	"*2013-03-12 v3.0.11 support L5\n"\
	"*2012-12-28 v3.0.10 add function trmem_decode_head\n"\
	"*2012-09-26 v3.0.8 add api append_v2 and set_v2_2\n"\
	"*2012-06-19 support incr\n"\
	"*2012-04-23 namespace for all headers\n"\
	"*2012-03-09 reconnect when connect is closed when timeout\n"\
	"*2011-12-21 cancel retry when timeout\n"\
	"*2011-10-19 fix bug about offset/len, support set_v2_1/setlist_v2_1/add/replace/append/prepend/insert by cjhuang\n"\
	"*2011-8-26 limit timeout, modify freeze problem by fridozhang\n"
	
namespace ssdasn {

class trmem_client_api
{
private:
	/*
	* 私有拷贝构造函数和拷贝赋值，防止按值传递将socket句柄传递
	*/
	trmem_client_api(const trmem_client_api& tOther)	{}
	const trmem_client_api& operator = (const trmem_client_api& tOther)	{return tOther;}
public:
	trmem_client_api();
	~trmem_client_api();

	/*
	*函数: Ver
	*功能: 用printf打印api版本信息
	*/
	void Ver();

	/*
	*函数: set_passwd
	*功能: 设置业务的访问密码
	*入参:
	*	bid - 业务bid
	*	pPasswd - 访问密码，8字节长度，16进制字符串，以'\0'为终止符
	*返回值:
	*	0 - 成功
	*	-11918 - 密码格式错误
	*/
	int set_passwd(int bid, char *pPasswd);

	/*
	*函数: GetLastErr
	*功能: 返回最后一次的错误信息
	*返回值:
	*	以'\0'为终止符的字符串信息
	*/
	char* GetLastErr();

	/*
	*函数: GetLastServer
	*功能: 获取最后一次请求发送的接入机信息
	*出参:
	*	pIP - 返回最后一次使用的接入机IP，NULL则不返回
	*	pPort - 返回最后一次使用的接入机Port，NULL则不返回
	*返回值:
	*	NULL - 没有请求的IP
	*	其它 - 返回最后一次请求的IP字符串
	*/
	const char* GetLastServer(std::string *pIP, unsigned short *pPort);

	/*
	*函数: config_l5_sid
	*功能: 配置接入机的l5信息
	*入参:
	*	modid - l5的modid
	*	cmdid - l5的cmdid
	*	timeout_ms - TCP收发包超时时间，范围[50ms,10000ms]，单位毫秒
	*	l5_timeout_s - l5连接超时时间，范围[0.001,1]，单位s
	*返回值:
	*	0 - 成功
	*注意:
	*	config_server_addr与config_l5_sid两者必须且只能选择其中方式指定接入机信息
	*	如果通过L5方式，请调用config_l5_sid设定L5的SID
	*	通过配置固定的接入机IP和Port，请调用config_server_addr
	*	使用L5时尽量采用api的L5的接口配置接入机信息，采用GetLastServer获取L5调用的结果
	*	api内嵌的L5为使用的长链接，并且可以屏蔽异常的接入机
	*	因此config_l5_sid比用户个人使用L5获取IP和Port后调用config_server_addr具有更高的性能和更快的容灾
	*/
	int config_l5_sid(int modid, int cmdid, unsigned int timeout_ms=10000, float l5_timeout_s=0.2);

	/*
	*函数: config_server_addr
	*功能: 配置接入机的IP和Port
	*入参:
	*	vaddr - 接入机IP和Port数组
	*	timeout_ms - TCP收发包超时时间，允许范围>= 50ms，单位毫秒
	*	iFreezeSecs - 接入机异常后冻结时间，如果接入机出现异常，则需等待超过冻结时间后，才能恢复为可用，允许范围是60s~300s
	*返回值:
	*	0 - 成功
	*注意:
	*	config_server_addr与config_l5_sid两者必须且只能选择其中方式指定接入机信息
	*	如果通过L5方式，请调用config_l5_sid设定L5的SID
	*	通过配置固定的接入机IP和Port，请调用config_server_addr
	*/
	int config_server_addr(vector<TServerAddr> &vaddr, unsigned int timeout_ms=10000, int iFreezeSecs=60);

	/*
	*函数: config_connect_timeout
	*功能: 设置TCP连接建立超时时间
	*入参:
	*	connect_timeout_ms - 设置的连接超时时间，允许范围>= 50ms，单位毫秒
	*返回值:
	*	0 - 成功
	*/
	int config_connect_timeout(unsigned int connect_timeout_ms=10000);

	/*-------------------------v1 version--------------------------------*/
	/*
	*函数: set
	*功能: 设置或替换指定key的数据，相比set_v2，不支持cas和expire
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	data - 设置或改写替换的数据
	*	replace_offset - 替换的开始偏移
	*	replace_len - 替换的长度
	*返回值:
	*	0 - 全部成功
	*	其它错误详见readme_errcode.txt
	*注意:
	*	set的替换有效判断为：replace_offset > 0 || repalce_len > 0
	*/
	int set(int bid, string &key, string &data, int replace_offset = 0, int replace_len = -1);

	/*
	*函数: get
	*功能: 查询指定key的数据，相比get_v2，不能查询cas和expire
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	offset - 查询的偏移
	*	len - 查询的数据长度
	*出参:
	*	data - 返回查询的数据
	*返回值:
	*	0 - 全部成功
	*	其它错误详见readme_errcode.txt
	*注意:
	*	offset >= 0 && len > 0 则认为是查询原始数据中的部分数据，否则取整个数据
	*/
	int get(int bid, string &key, string &data, int offset = 0, int len = -1);

	/*
	*函数: del
	*功能: 删除指定key，相比del_v2，不能指定cas
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*返回值:
	*	0 - 全部成功
	*	其它错误详见readme_errcode.txt
	*/
	int del(int bid, string &key);

	/*
	*函数: setlist
	*功能: 批量查询，TKeyNodeV2结构体内参数意义同get_v2，相比setlist_v2，不支持cas和expire
	*入参:
	*	bid - 业务bid
	*	v_node - 批量查询操作的节点
	*返回值:
	*	0 - 全部成功
	*	>0 - 操作失败的个数
	*	< 0 - 其它错误详见readme_errcode.txt
	*/
	int setlist(int bid, vector<TKeyNode> &v_node);

	/*
	*函数: getlist
	*功能: 批量查询，TKeyNode结构体内参数意义同get，相比getlist_v2，不能查询返回cas和expire
	*入参:
	*	bid - 业务bid
	*	v_node - 批量查询操作的节点
	*返回值:
	*	0 - 全部成功
	*	>0 - 操作失败的个数
	*	< 0 - 其它错误详见readme_errcode.txt
	*/
	int getlist(int bid, vector<TKeyNode> &v_node);

	/*
	*函数: dellist
	*功能: 批量删除，TKeyNode结构体内参数意义同del，相比dellist_v2，不能指定cas
	*入参:
	*	bid - 业务bid
	*	v_node - 批量删除操作的节点
	*返回值:
	*	0 - 全部成功
	*	>0 - 操作失败的个数
	*	< 0 - 其它错误详见readme_errcode.txt
	*/
	int dellist(int bid, vector<TKeyNode> &v_node);


	/*-------------------------v2 version--support cas and timeout--------------------*/

	/*
	*函数: set_v2
	*功能: 设置或替换指定key的数据，相比set，可以使用cas和expire
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	data - 设置或改写替换的数据
	*	cas - cas值，意义详见CKV KM吧
	*	expire - 超时时间偏移，超时后数据将变为无效,0或负值表示永不超时,单位为秒
	*	offset - 替换的开始偏移
	*	len - 替换的长度
	*返回值:
	*	0 - 全部成功
	*	其它错误详见readme_errcode.txt
	*注意:
	*	set_v2与set_v2_1和set_v2_2的区别在于替换时的有效判断不同
	*	set_v2的替换有效判断为：replace_offset > 0 || repalce_len > 0
	*/
	int set_v2(int bid, string &key, string &data, int &cas, int expire = 0, int offset = 0, int len = -1);

	/*
	*函数: get_v2
	*功能: 查询指定key的数据，相比get，可以返回cas和expire
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	offset - 查询的偏移
	*	len - 查询的数据长度
	*出参:
	*	data - 返回查询的数据
	*	cas - cas值，意义详见CKV KM吧
	*	rsp_ext - 返回expire，不需要查询时填NULL
	*返回值:
	*	0 - 全部成功
	*	其它错误详见readme_errcode.txt
	*注意:
	*	offset >= 0 && len > 0 则认为是查询原始数据中的部分数据，否则取整个数据
	*/
	int get_v2(int bid, string &key, string &data, int &cas, int offset = 0, int len = -1, TRspExt* rsp_ext = NULL);

	/*
	*函数: del_v2
	*功能: 删除指定key，相比del，可以指定cas
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	cas - cas值，意义详见CKV KM吧
	*返回值:
	*	0 - 全部成功
	*	-13104 - cas不匹配，该key可能已经被修改
	*	其它错误详见readme_errcode.txt
	*/
	int del_v2(int bid, string &key, int cas = -1);

	/*
	*函数: setlist_v2
	*功能: 批量查询，TKeyNodeV2结构体内参数意义同get_v2，相比setlist，可以设置cas和expire
	*入参:
	*	bid - 业务bid
	*	v_node - 批量查询操作的节点
	*返回值:
	*	0 - 全部成功
	*	>0 - 操作失败的个数
	*	< 0 - 其它错误详见readme_errcode.txt
	*注意:
	*	setlist_v2,对于不同key,不能进行部分数据操作和expire操作
	*	实际此类调用时不会产生错误，但内部已经拆成了单条set_v2串行执行
	*/
	int setlist_v2(int bid, vector<TKeyNodeV2>& v_node);

	/*
	*函数: getlist_v2
	*功能: 批量查询，TKeyNodeV2结构体内参数意义同get_v2，相比getlist，可以查询返回cas和expire
	*入参:
	*	bid - 业务bid
	*	v_node - 批量查询操作的节点
	*返回值:
	*	0 - 全部成功
	*	>0 - 操作失败的个数
	*	< 0 - 其它错误详见readme_errcode.txt
	*/
	int getlist_v2(int bid, vector<TKeyNodeV2>& v_node);

	/*
	*函数: dellist_v2
	*功能: 批量删除，TKeyNodeV2结构体内参数意义同del_v2，相比dellist，可以指定cas
	*入参:
	*	bid - 业务bid
	*	v_node - 批量删除操作的节点
	*返回值:
	*	0 - 全部成功
	*	>0 - 操作失败的个数
	*	< 0 - 其它错误详见readme_errcode.txt
	*/
	int dellist_v2(int bid, vector<TKeyNodeV2>& v_node);	

	/*--------------------------support column operation--------------------*/
	/*
	*函数: set_col
	*功能: 设置指定key的指定列数据
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	col - 列号，0~511
	*	data - 设置的数据，将设置到指定key的指定列中
	*	cas - cas值，意义详见CKV KM吧
	*返回值:
	*	0 - 全部成功
	*	-13104 - cas不匹配，该key可能已经被修改
	*	其它错误详见readme_errcode.txt
	*/
	int set_col(int bid, string &key, unsigned int col, string &data, int &cas); 
	
	/*
	*函数: get_col
	*功能: 查询指定key的指定列数据
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	col - 列号，0~511
	*出参:
	*	data - 获得的数据
	*	cas - 用于返回当前的cas值,-1表示无需cas
	*返回值:
	*	0 - 全部成功
	*	其它错误详见readme_errcode.txt
	*/
	int get_col(int bid, string &key, unsigned int col, string &data, int &cas); 

	
	/*
	*函数: del_col
	*功能: 删除指定key的指定列数据，具体删除为将该列长度置为0,列的结构不会变化
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	col - 列号，0~511
	*	cas - cas值，意义详见CKV KM吧
	*返回值:
	*	0 - 全部成功
	*	-13104 - cas不匹配，该key可能已经被修改
	*	其它错误详见readme_errcode.txt
	*/
	int del_col(int bid, string &key, unsigned int col, int &cas); 

	/*
	*函数: set_mul_col
	*功能: 设置单key的多列数据，TKeySetListNode内参数意义同set_col
	*入参:
	*	bid - 业务bid
	*	node - 待设置的列信息
	*返回值:
	*	0 - 全部成功
	*	>0 - 操作失败的个数
	*	-11910 - 错误的列ID
	*	-11911 - 批量为空
	*	其它错误详见readme_errcode.txt
	*/
	int set_mul_col(int bid, TKeySetListNode& node); 
	
	/*
	*函数: get_mul_col
	*功能: 查询单key的多列数据，TKeyGetListNode内参数意义同get_col
	*入参:
	*	bid - 业务bid
	*	node - 待查询的列信息
	*返回值:
	*	0 - 全部成功
	*	>0 - 操作失败的个数
	*	-11910 - 错误的列ID
	*	-11911 - 批量为空
	*	其它错误详见readme_errcode.txt
	*/
	int get_mul_col(int bid, TKeyGetListNode & node); 
	
	/*
	*函数: del_mul_col
	*功能: 删除单key的多列数据，TKeyDelListNode内参数意义同del_col
	*入参:
	*	bid - 业务bid
	*	node - 待删除的列信息
	*返回值:
	*	0 - 全部成功
	*	>0 - 操作失败的个数
	*	-11910 - 错误的列ID
	*	-11911 - 批量为空
	*	其它错误详见readme_errcode.txt
	*/
	int del_mul_col(int bid, TKeyDelListNode & node); 
	
	/*
	*函数: setlist_mul_col
	*功能: 批量设置一个或多个key的一个或多个指定列，TKeySetListNode内参数意义同set_mul_col
	*入参:
	*	bid - 业务bid
	*	v_node - 批量设置的节点
	*返回值:
	*	0 - 全部成功
	*	>0 - 操作失败的个数
	*	-11910 - 错误的列ID
	*	-11911 - 批量为空
	*	其它错误详见readme_errcode.txt
	*注意:
	*	具体的每个节点操作的返回值见v_node内的retcode，其具体意义参考set_col
	*/
	int setlist_mul_col(int bid, vector< TKeySetListNode>& v_node); 
	
	/*
	*函数: getlist_mul_col
	*功能: 批量查询一个或多个key的一个或多个指定列，TKeyGetListNode内参数意义同get_mul_col
	*入参:
	*	bid - 业务bid
	*	v_node - 批量查询的节点
	*返回值:
	*	0 - 全部成功
	*	>0 - 操作失败的个数
	*	-11910 - 错误的列ID
	*	-11911 - 批量为空
	*	其它错误详见readme_errcode.txt
	*注意:
	*	具体的每个节点操作的返回值见v_node内的retcode，其具体意义参考get_col
	*/
	int getlist_mul_col(int bid, vector< TKeyGetListNode>& v_node);

	/*
	*函数: dellist_mul_col
	*功能: 批量删除一个或多个key的一个或多个指定列，TKeyDelListNode内参数意义同del_mul_col
	*入参:
	*	bid - 业务bid
	*	v_node - 批量删除的节点
	*返回值:
	*	0 - 全部成功
	*	>0 - 操作失败的个数
	*	-11910 - 错误的列ID
	*	-11911 - 批量为空
	*	其它错误详见readme_errcode.txt
	*注意:
	*	具体的每个节点操作的返回值见v_node内的retcode，其具体意义参考del_col
	*/
	int dellist_mul_col(int bid, vector< TKeyDelListNode >& v_node);

	/*--- v2_1 version--fix bugs: offset and len, strErr, strlen(key)>=2, get_host_info; support add/replace/append/prepend/insert ---*/

	/*
	*函数: set_v2_1
	*功能: 设置或替换value，相比set_v2_2，不会返回操作后value的长度
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	data - 设置或替换的数据
	*	cas - cas值，意义详见CKV KM吧
	*	expire - 超时时间偏移，超时后数据将变为无效,0或负值表示永不超时,单位为秒
	*	offset - 替换的开始偏移
	*	len - 替换的长度
	*返回值:
	*	0 - 成功
	*	-13105 - key不存在
	*	其它错误详见readme_errcode.txt
	*注意:
	*	set_v2_1与set_v2的区别在于替换时的有效判断不同
	*	set_v2_1替换有效的判断逻辑: replace_offset >= -1 && repalce_len >= -1 && (replace_offset != -1 || replace_len != -1)
	*	若落地数据中有key的数据，则进行相应的替换。
	*	如落地数据中无key指定的数据，而replace部分是有效值，则返回出错
	*/
	int set_v2_1(int bid, string &key, string &data, int &cas, int expire = 0, int offset = 0, int len = -1);

	/*
	*函数: setlist_v2_1
	*功能: 批量的set_v2_1接口，TKeyNodeV2内参数意义同set_v2_1
	*入参: 
	*	bid - 业务bid
	*	v_node - 批量设置的操作节点
	*返回值:
	*	0 - 全部成功
	*	>0 - 操作失败的个数
	*	-11911 - 批量为空
	*注意:
	*	setlist_v2_1与setlist_v2的区别在于替换时的有效判断不同，具体参考set_v2_1同set_v2的不同
	*	具体的每个节点操作的返回值见v_node内的retcode，其具体意义参考set_v2_1
	*/
	int setlist_v2_1(int bid, vector<TKeyNodeV2>& v_node);

	/*
	*函数: add
	*功能: 增加key-value，只有不存在的key才能成功加入，否则返回失败
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	data - 设置的数据
	*	expire - 超时时间偏移，超时后数据将变为无效,0或负值表示永不超时,单位为秒
	*返回值:
	*	0 - 成功
	*	-13109 - key已经存在
	*	其它错误详见readme_errcode.txt
	*/
	int add(int bid, string &key, string &data, int expire=0);

	/*
	*函数: replace
	*功能: 替换value
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	data - 替换的数据
	*	cas - cas值，意义详见CKV KM吧
	*	expire - 超时时间偏移，超时后数据将变为无效,0或负值表示永不超时,单位为秒
	*	offset - 替换的开始偏移
	*	len - 替换的长度
	*返回值:
	*	0 - 成功
	*	-13105 - key不存在
	*	其它错误详见readme_errcode.txt
	*注意:
	*	replace部分有效的判断逻辑: replace_offset >= -1 && repalce_len >= -1 && (replace_offset != -1 || replace_len != -1)
	*	若落地数据中有key的数据，则进行相应的替换。
	*	如落地数据中无key指定的数据，而replace部分是有效值，则返回出错
	*/
	int replace(int bid, string &key, string &data, int &cas, int expire = 0, int offset = 0, int len = -1);

	/*
	*函数: append
	*功能: 尾部添加，相比append_v2，无法返回操作后value的长度
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	data - 插入的value
	*	cas - cas值，意义详见CKV KM吧
	*	expire - 超时时间偏移，超时后数据将变为无效,0或负值表示永不超时,单位为秒
	*返回值:
	*	0 - 成功
	*	-13105 - key不存在
	*	其它错误详见readme_errcode.txt
	*/
	int append(int bid, string &key, string &data, int &cas, int expire = 0);

	/*
	*函数: set_v2_2
	*功能: 设置或替换value，相比set_v2_1，可以返回操作后value的长度
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	data - 设置或替换的数据
	*	cas - cas值，意义详见CKV KM吧
	*	expire - 超时时间偏移，超时后数据将变为无效,0或负值表示永不超时,单位为秒
	*	offset - 替换的开始偏移
	*	len - 替换的长度
	*出参:
	*	value_len: 返回set后value的长度。如果是-1，表示后台不支持返回value长度
	*返回值:
	*	0 - 成功
	*	-13105 - key不存在
	*	其它错误详见readme_errcode.txt
	*注意:
	*	set_v2_2与set_v2的区别在于替换时的有效判断不同
	*	set_v2_2替换有效的判断逻辑: replace_offset >= -1 && repalce_len >= -1 && (replace_offset != -1 || replace_len != -1)
	*	若落地数据中有key的数据，则进行相应的替换。
	*	如落地数据中无key指定的数据，而replace部分是有效值，则返回出错
	*/
	int set_v2_2(int bid, string &key, string &data, int &cas, int &value_len, int expire = 0, int offset = 0, int len = -1);

	/*
	*函数: append_v2
	*功能: 尾部添加，相比append，可以返回操作后value的长度
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	data - 插入的value
	*	cas - cas值，意义详见CKV KM吧
	*	expire - 超时时间偏移，超时后数据将变为无效,0或负值表示永不超时,单位为秒
	*出参:
	*	value_len - 返回添加操作后，value的长度。如果为-1，则表示服务端还不支持返回
	*返回值:
	*	0 - 成功
	*	-13002 - key不存在
	*	其它错误详见readme_errcode.txt
	*/
	int append_v2(int bid, string &key, string &data, int &cas, int &value_len, int expire = 0);

	/*
	*函数: prepend
	*功能: 首部添加，如果key不存在则为set操作
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	data - 插入的value
	*	cas - cas值，意义详见CKV KM吧
	*	expire - 超时时间偏移，超时后数据将变为无效,0或负值表示永不超时,单位为秒
	*返回值:
	*	0 - 成功
	*	其它错误详见readme_errcode.txt
	*/
	int prepend(int bid, string &key, string &data, int &cas, int expire = 0);

	/*
	*函数: inset
	*功能: 插入操作
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	data - 插入的value
	*	cas - cas值，意义详见CKV KM吧
	*	expire - 超时时间偏移，超时后数据将变为无效,0或负值表示永不超时,单位为秒
	*	offset - 插入的偏移值，是指已经缓存在CKV中的数据，并非当前输入的data
	*返回值:
	*	0 - 成功
	*	-13002 - offset大于CKV中已经存在的数据的长度
	*注意:
	*	当key不存在，CKV中的数据长度看作0
	*/
	int insert(int bid, string &key, string &data, int &cas, int expire, int offset);

	/*
	*函数: incr_create
	*功能: incr初始化为特定值，仅当key不存在时，才能调用成功，将value初始化为指定值
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	value - 初始化的值
	*返回值:
	*	0 - 成功
	*	-13104 - 该key已存在
	*	其它错误详见readme_errcode.txt
	*注意:
	*	incr操作的key必须不能跟set/get接口混用，可以调用del删除
	**/
	int incr_create(int bid, string &key, uint64_t value = 0);
	
	/*
	*函数: incr_init
	*功能: incr初始化为特定值，key不存在时则创建，存在时则相当于将value重置为传入值
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	value - 初始化或重置的值
	*返回值:
	*	0 - 成功
	*	其它错误详见readme_errcode.txt
	*注意:
	*	incr操作的key必须不能跟set/get接口混用，可以调用del删除
	**/
	int incr_init(int bid, string &key, uint64_t value = 0);
	/*
	*函数: incr_value
	*功能: incr指定值，如果是负值，则相当于decr操作，最终结果如果小于0，则被置为0
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	value - 执行incr的操作值
	*返回值:
	*	0 - 成功
	*	-13105 - 操作的key未创建
	*	其它错误详见readme_errcode.txt
	**/
	int incr_value(int bid, string &key, int64_t value);
	/*
	*函数: incr_value_v2
	*功能: incr指定值，同incr_value区别为：value会返回当次incr操作后的值
	*入参:
	*	bid - 业务bid
	*	key - 操作的key
	*	value - 执行incr的操作值
	*出参:
	*	value - 成功时，返回当次操作后的value
	*返回值:
	*	0 - 成功
	*	-13105 - 操作的key未创建
	*	其它错误详见readme_errcode.txt
	**/
	int incr_value_v2(int bid, string &key, int64_t& value);
	/*
	*函数: incr_get
	*功能: 获取incr操作数据结果
	*入参:
	*	bid - 业务bid
	*	key - 查询的key
	*出参:
	*	value - 成功时，返回查询的key的value
	*返回值:
	*	0 - 成功
	*	-13200 - 查询的key不存在
	*	其它错误详见readme_errcode.txt
	**/
	int incr_get(int bid, string &key, uint64_t &value);

	private:
	int _req_cache(int bid, int cache_op, string &key, string &data, int &cas, int expire = 0, int replace_offset = 0, int replace_len = -1, TRspExt *rsp_ext = NULL, TReqExt *req_ext = NULL);	
	int _req_list(int bid, int cache_op, vector<TKeyNode> &v_node);
	int _req_list_v2(int bid, int cache_op, vector<TKeyNodeV2> &v_node);
	int _req_list_internal(int bid, int cache_op, vector<TKeyNodeInternal> &v_node);
	int ConnServer(unsigned int ip, unsigned short  port, unsigned int timeout_ms);
	int _req_dist_server(string &key, char *req_data, int req_len, int *rsp_len);
	int _req_dist_server_fixip(string &key, char *req_data, int req_len, int *rsp_len);
	int _req_dist_server_l5(string &key, char *req_data, int req_len, int *rsp_len);

	
	int send_msg(char *data, int data_len, int sock_fd);
	int recv_msg(int *real_len, int sock_fd);
	int SockReadable(int sock_fd, int timeout_ms);
	int SockWriteable(int sock_fd, int timeout_ms);
	int _subsetlist(int bid, vector<TKeyNode> &v_node);
	int _subgetlist(int bid, vector<TKeyNode> &v_node);
	int _subdellist(int bid, vector<TKeyNode> &v_node);
	int _fromsublist(vector< vector<TKeyNode> > &v_subNodeVec, vector<TKeyNode> &v_node);
	int _tosublist(vector<TKeyNode> &v_node, vector< vector<TKeyNode> > &v_subNodeVec);

	int _subgetlist_v2(int bid, vector<TKeyNodeV2>& v_node);
	int _fromsublistv2(vector< vector<TKeyNodeV2> > &v_subNodeVec, vector<TKeyNodeV2> &v_node);
	int _tosublistv2(vector<TKeyNodeV2> &v_node, vector< vector<TKeyNodeV2> > &v_subNodeVec);

	int _subgetlist_mul_col(int bid, vector< TKeyGetListNode>& v_node);
	int _fromsublistmulcol(vector< vector<TKeyGetListNode> > &v_subNodeVec, vector< TKeyGetListNode>& v_node);
	int _tosublistmulcol(vector< TKeyGetListNode>& v_node, vector< vector<TKeyGetListNode> > &v_subNodeVec);

	map<string, THostCtrl> mapHost;
	char m_szLastHost[16]; /* last host ip buffer */
	unsigned short m_usLastPort; /*last host port*/

	bool m_useL5;
	int m_modid;
	int m_cmdid;

	time_t m_last_clean_svr_time;

	CCharBuffer m_send_buff;	
	CCharBuffer m_recv_buff;
	int msg_seq;
	char strErr[512];

	int HOST_FROZEN_INTERVAL;
	unsigned int m_timeout_ms;
	unsigned int m_connect_timeout_ms;	
	float m_l5_timeout_s;
	map<int, int> mapBidPasswd;
public:
	/*
	* fd信息被置为-1,避免被外部修改
	*/
	void get_host_info(vector<THostCtrl> &vec);
	void get_host_info(map<string, THostCtrl> &map);

	TStatistics m_TStatistics;//外部可直接读取
};

}

#endif//__TRMEM_CACHE_LIB_H__

